import { sanitizeHtml, validateHtmlContent, createStyleIsolatedHtml, createShadowRoot } from '../utils/safeHtml'

interface SafeHtmlBinding {
  content: string
  config?: {
    allowTags?: string[]
    allowAttrs?: string[]
    customConfig?: Record<string, unknown>
    useSandbox?: boolean
    sandboxId?: string
  }
}

/**
 * v-safe-html 自定义指令
 * 用于安全地渲染HTML内容，防止XSS攻击
 */
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.directive('safe-html', {
    mounted(el, binding) {
      updateElementContent(el, binding.value)
    },
    updated(el, binding) {
      // 只在内容真正改变时更新
      if (binding.value !== binding.oldValue) {
        updateElementContent(el, binding.value)
      }
    }
  })
})

/**
 * 更新元素的安全HTML内容
 */
function updateElementContent(el: HTMLElement, bindingValue: SafeHtmlBinding | string) {
  try {
    let content: string
    let config: {
      allowTags?: string[]
      allowAttrs?: string[]
      customConfig?: Record<string, unknown>
      useSandbox?: boolean
      sandboxId?: string
    } = {}

    // 处理不同的绑定值类型
    if (typeof bindingValue === 'string') {
      content = bindingValue
      // 字符串用法默认启用沙盒环境
      config.useSandbox = true
    } else if (bindingValue && typeof bindingValue === 'object') {
      content = bindingValue.content || ''
      if (bindingValue.config) {
        config = bindingValue.config
      }
      // 确保对象用法也默认启用沙盒环境（如果没有明确设置）
      if (config.useSandbox === undefined) {
        config.useSandbox = true
      }
    } else {
      content = String(bindingValue || '')
      // 其他类型默认启用沙盒环境
      config.useSandbox = true
    }

    // 验证内容
    if (!content || typeof content !== 'string') {
      el.innerHTML = ''
      return
    }

    // 基本的内容验证
    if (!validateHtmlContent(content)) {
      console.warn('HTML内容未通过安全验证，已过滤')
      el.innerHTML = ''
      return
    }

    // 构建清理配置
    const sanitizeConfig: Record<string, unknown> = {}
    if (config.customConfig) {
      Object.assign(sanitizeConfig, config.customConfig)
    }

    // 只有在提供自定义标签和属性时才设置
    if (config.allowTags && config.allowTags.length > 0) {
      sanitizeConfig.ALLOWED_TAGS = config.allowTags
    }
    if (config.allowAttrs && config.allowAttrs.length > 0) {
      sanitizeConfig.ALLOWED_ATTR = config.allowAttrs
    }

    // 使用DOMPurify清理HTML
    const cleanedHtml = sanitizeHtml(content, sanitizeConfig)

    // 验证清理后的结果
    if (!cleanedHtml) {
      console.warn('HTML内容清理后为空')
      el.innerHTML = ''
      return
    }

    // 检查是否需要沙盒环境隔离
    const useSandbox = config.useSandbox ?? true // 默认启用沙盒隔离
    
    if (useSandbox) {
      // 创建样式隔离的HTML内容
      const isolatedHtml = createStyleIsolatedHtml(cleanedHtml, {
        sandboxId: config.sandboxId,
        useShadowDom: true,
        prefixSelector: config.sandboxId ? `#${config.sandboxId}` : undefined
      })
      
      // 创建Shadow DOM根元素
      const shadowContainer = document.createElement('div')
      shadowContainer.className = 'safe-html-shadow-container'
      el.innerHTML = '' // 清空原始内容
      el.appendChild(shadowContainer)
      
      // 使用Shadow DOM创建真正的样式隔离
      createShadowRoot(shadowContainer, isolatedHtml)
    } else {
      // 如果不使用沙盒，直接设置innerHTML（不推荐）
      console.warn('未启用沙盒环境隔离，可能存在样式污染风险')
      el.innerHTML = cleanedHtml
    }

  } catch (error) {
    console.error('HTML内容清理过程出错:', error)
    el.innerHTML = ''
  }
}